﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ObjectEqualityHelpers.cs" company="AzureContrib (Open source library http://azurecontrib.codeplex.com)">
//   Microsoft Public License (Ms-PL)
// </copyright>
// <summary>
//   Some helpers for equating objects.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System.Diagnostics.CodeAnalysis;

namespace AzureContrib.WindowsAzure
{
	/// <summary>
	/// Some helpers for equating objects.
	/// </summary>
	public static class ObjectEqualityHelpers
	{
		/// <summary>
		/// Either parameter is null
		/// </summary>
		/// <param name="first">The first object.</param>
		/// <param name="second">The second object.</param>
		/// <returns>True if either of the parameters is null.</returns>
		public static bool EitherIsNull(object first, object second)
		{
			return Equals(first, null) || 
						 Equals(second, null);
		}

		/// <summary>
		/// One of the two parameters is null
		/// </summary>
		/// <param name="first">The first object.</param>
		/// <param name="second">The second object.</param>
		/// <returns>True if one of the two parameters is null.</returns>
		public static bool OnlyOneIsNull(object first, object second)
		{
			return (Equals(first, null) && !Equals(second, null)) ||
						 (!Equals(first, null) && Equals(second, null));
		}

		/// <summary>
		/// Are the two parameters equatable? If <see cref="EitherIsNull"/> while <see cref="OnlyOneIsNull"/> then they equating them is not valid.
		/// </summary>
		/// <param name="first">The first object.</param>
		/// <param name="second">The second object.</param>
		/// <param name="result">If both are null true. If one is null false.</param>
		/// <returns>True if neither is null.</returns>
		/// <remarks>If the retun is true then return the <paramref name="result"/>!</remarks>
		[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Justification = "There are three outcomes of this method that's why using two booleans is correct. When the return is true the value of the out is used.")]
		public static bool NotEquatable(object first, object second, out bool result)
		{
			if (EitherIsNull(first, second))
			{
				result = !OnlyOneIsNull(first, second);
				return true;
			}

			result = false;
			return false;
		}
	}
}